package com.world.rickcloudendpoint.service.net.websocket;

import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: netty web socket 服务端缓存器
 * @author: jlsong
 * @date: 2021/12/08 21:31:15
 * @version: 1.0
 */
@Component
public class SocketChannelCache {

    public SocketChannelCache() {
    }

    /**
     * 连接通道集合缓存
     */
    private static final ConcurrentHashMap<String, HashMap<String, Channel>> CACHE_MAP = new ConcurrentHashMap<>();

    /**
     * 连接通道属性关键字
     */
    private static final AttributeKey<String> CHANNEL_ATTR_KEY = AttributeKey.valueOf("test");

    /**
     * 通过连接通道获取缓存标识
     *
     * @param channel 连接通道
     * @return 缓存标识
     */
    public String getCacheId(Channel channel) {
        return channel.attr(CHANNEL_ATTR_KEY).get();
    }

    /**
     * 将连接通道通过唯一标识缓存起来
     *
     * @param cacheId 缓存标识
     * @param channel 连接通道
     */
    public void add(String cacheId, Channel channel) {
        channel.attr(CHANNEL_ATTR_KEY).set(cacheId);
        HashMap<String, Channel> hashMap = CACHE_MAP.get(cacheId);
        if (hashMap == null) {
            hashMap = new HashMap<>();
        }
        hashMap.put(channel.id().asShortText(), channel);
        CACHE_MAP.put(cacheId, hashMap);
    }

    /**
     * 通过缓存标识获取连接通道集合
     *
     * @param cacheId 缓存标识
     * @return 连接通道集合
     */
    public HashMap<String, Channel> get(String cacheId) {
        if (cacheId == null) {
            return null;
        }
        return CACHE_MAP.get(cacheId);
    }

    /**
     * 通过连接通道移除缓存中的通道集合
     *
     * @param channel 连接通道
     */
    public void remove(Channel channel) {
        String cacheId = getCacheId(channel);
        if (cacheId == null) {
            return;
        }
        HashMap<String, Channel> hashMap = CACHE_MAP.get(cacheId);
        if (hashMap == null) {
            hashMap = new HashMap<>();
        }
        hashMap.remove(channel.id().asShortText());
        CACHE_MAP.put(cacheId, hashMap);
    }


}
